<template>
  <div>
    <!-- 容器 -->
    <div class="container">
      <!-- 操作区域 -->
      <div class="handle-box">
        <!-- 文件上传组件 -->
        <el-upload
          action="#"
          :limit="1"
          accept=".xlsx, .xls"
          :show-file-list="false"
          :before-upload="beforeUpload"
          :http-request="handleMany"
        >
          <!-- 上传按钮 -->
          <el-button class="mr10" type="success">批量导入</el-button>
        </el-upload>
        <!-- 下载模板链接 -->
        <el-link href="/template.xlsx" target="_blank">下载模板</el-link>
      </div>
      <!-- 数据表格 -->
      <el-table :data="tableData" border class="table" header-cell-class-name="table-header">
        <!-- ID列 -->
        <el-table-column prop="id" label="ID" width="55" align="center"></el-table-column>
        <!-- 姓名列 -->
        <el-table-column prop="name" label="姓名"></el-table-column>
        <!-- 学号列 -->
        <el-table-column prop="sno" label="学号"></el-table-column>
        <!-- 班级列 -->
        <el-table-column prop="class" label="班级"></el-table-column>
        <!-- 年龄列 -->
        <el-table-column prop="age" label="年龄"></el-table-column>
        <!-- 性别列 -->
        <el-table-column prop="sex" label="性别"></el-table-column>
      </el-table>
    </div>
  </div>
</template>

<script setup lang="ts" name="import">
// 导入 Element Plus 的 UploadProps 类型（仅类型导入）
import type { UploadProps } from 'element-plus';
// 导入 Vue 的响应式引用
import { ref } from 'vue';
// 导入 XLSX 库用于解析 Excel 文件
import * as XLSX from 'xlsx';

// 定义表格数据项的接口
interface TableItem {
  id: number;
  name: string;
  sno: string;
  class: string;
  age: string;
  sex: string;
}

// 定义从 Excel 导入的数据项接口
interface ExcelDataItem {
  [key: string]: any; // 允许任意字符串键，值为任意类型
}

// 创建响应式的表格数据引用
const tableData = ref<TableItem[]>([]);

// 获取初始表格数据
const getData = () => {
  tableData.value = [
    {
      id: 1,
      name: '小明',
      sno: 'S001',
      class: '一班',
      age: '10',
      sex: '男',
    },
    {
      id: 2,
      name: '小红',
      sno: 'S002',
      class: '一班',
      age: '9',
      sex: '女',
    },
  ];
};
getData();

// 创建响应式的导入数据列表引用
const importList = ref<ExcelDataItem[]>([]);

// 上传前的处理函数
const beforeUpload: UploadProps['beforeUpload'] = async rawFile => {
  // 解析 Excel 文件并存储到 importList 中
  importList.value = await analysisExcel(rawFile);
  return true;
};

// 解析 Excel 文件的函数
const analysisExcel = (file: any) => {
  // 返回一个 Promise，用于异步处理文件解析
  return new Promise<ExcelDataItem[]>((resolve, reject) => {
    // 创建文件读取器
    const reader = new FileReader();
    // 文件加载完成后的回调函数
    reader.onload = function (e: any) {
      // 获取文件数据
      const data = e.target.result;
      // 使用 XLSX 读取二进制数据
      const datajson = XLSX.read(data, {
        type: 'binary',
      });

      // 获取第一个工作表的名称
      const sheetName = datajson.SheetNames[0];
      // 检查工作表是否存在
      if (sheetName && datajson.Sheets.hasOwnProperty(sheetName)) {
        // 获取工作表数据
        const sheet = datajson.Sheets[sheetName]!;
        // 将工作表转换为 JSON 格式
        const result = XLSX.utils.sheet_to_json(sheet) as ExcelDataItem[];
        // 解析成功，返回结果
        resolve(result);
      } else {
        // 工作表不存在，拒绝 Promise
        reject(new Error('无法找到有效的工作表'));
      }
    };
    // 以二进制字符串格式读取文件
    reader.readAsBinaryString(file);
  });
};

// 处理批量导入的函数
const handleMany = async () => {
  // 把数据传给服务器后获取最新列表，这里只是示例，不做请求
  // 将导入的数据映射为表格数据格式
  const list = importList.value.map((item, index) => {
    // 添加类型检查，确保属性存在且不为 undefined，使用空值合并操作符提供默认值
    return {
      id: index, // 使用索引作为 ID
      name: item['姓名'] ?? '', // 获取姓名字段，如果不存在则为空字符串
      sno: item['学号'] ?? '', // 获取学号字段，如果不存在则为空字符串
      class: item['班级'] ?? '', // 获取班级字段，如果不存在则为空字符串
      age: item['年龄'] ?? '', // 获取年龄字段，如果不存在则为空字符串
      sex: item['性别'] ?? '', // 获取性别字段，如果不存在则为空字符串
    };
  });
  // 将处理后的数据添加到表格数据中
  tableData.value.push(...list);
};
</script>

<style scoped>
/* 操作区域样式 */
.handle-box {
  display: flex;
  margin-bottom: 20px;
}

/* 表格样式 */
.table {
  width: 100%;
  font-size: 14px;
}
</style>
